﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;

namespace OpenLS.Spreadsheet.Formats.Biff.Records
{
    class XFExtGradient: ExtPropValueBase
    {
        private XFPropGradient _gradient;
        private readonly List<GradStop> _rgGradStops = new List<GradStop>();

        internal XFExtGradient(GradientFill gradientFill)
        {
            Contract.Requires(gradientFill != null);
            Contract.Ensures(this.ToFill().Equals(gradientFill));
            _gradient=  new XFPropGradient(gradientFill);
            foreach (var stop in gradientFill.Stops)
                this._rgGradStops.Add(new GradStop(stop));
#if DEBUG
            bool b = ToFill().Equals(gradientFill);
            if (!b)
            {
                b = ToFill().Equals(gradientFill);
                Contract.Assert(ToFill().Equals(gradientFill));
            }
#endif
            

        }

        public XFExtGradient()
        {
        }

        public override void Read(BinaryReader reader)
        {
#if DEBUG
            ReadWriteChecker.CheckClass((t, r) => t.Read(r),
                                        (t, w) => t.Write(w), reader, this);
#endif

            this._gradient = new XFPropGradient();
            _gradient.Read(reader);
            uint cGradStops = reader.ReadUInt32();
            this._rgGradStops.Clear();
            for (int i = 0; i < cGradStops; i++)
            {
                GradStop g = new GradStop();
                g.Read(reader);
                this._rgGradStops.Add(g);
            }
        }

        public override int Length
        {
            get { return 4 + XFPropGradient.Length + _rgGradStops.Count* GradStop.Length; }
        }

        public override void Write(BinaryWriter writer)
        {
            this._gradient.Write(writer);
            uint u = (uint) this._rgGradStops.Count;
            writer.Write(u);
            foreach (var item in _rgGradStops)
                item.Write(writer);
        }

        public GradientFill ToFill()
        {
            Contract.Ensures(Contract.Result<GradientFill>() != null);
            GradientFill gradientFill = _gradient.ToFill();

            foreach (var item in _rgGradStops)
            {
                gradientFill.Stops.Add(item.ToStop());
            }
            return gradientFill;
        }
    }
}